#include "thread/loop_thread.h"
#include "loop/loop.h"

loop_thread::loop_thread(const loop_thread::init_callback &cb/* = thread_init_callback()*/) 
    : m_loop(nullptr)
{
}

loop_thread::~loop_thread()
{
    stop_loop();
}

loop* loop_thread::start_loop()
{
    m_thread = std::thread(&loop_thread::thread_func, this);

    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_cond.wait(lock, [this]() -> bool {
            return this->m_loop != nullptr;
        });
    }

    return m_loop;
}

void loop_thread::stop_loop()
{
    if (m_loop)
    {
        m_loop->quit();
    }
    if (m_thread.joinable())
    {
        m_thread.join();
    }
    m_loop = nullptr;
}

void loop_thread::thread_func()
{
    loop loop;

    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_loop = &loop;
        m_cond.notify_one();
    }

    loop.run();

    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_loop = nullptr;
    }
}